from rest_framework.response import Response

from django_demo.views import MyTokenObtainPairSerializer
from users.models import User, Clazz
from users.serializers import UserFormSerializer, ClazzSerializer
from rest_framework.viewsets import ModelViewSet, GenericViewSet
from rest_framework.pagination import PageNumberPagination
from rest_framework.decorators import action
from rest_framework.permissions import AllowAny
from django.contrib.auth.hashers import check_password
from rest_framework_simplejwt.tokens import RefreshToken


class UserView(ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserFormSerializer
    pagination_class = PageNumberPagination
    pagination_class.page_size_query_param = "rows"


class ClazzView(ModelViewSet):
    queryset = Clazz.objects.filter(delete=False).order_by("-id")
    serializer_class = ClazzSerializer

    pagination_class = PageNumberPagination
    pagination_class.page_size_query_param = "rows"
    pagination_class.page_size = 10

    def create(self, request, *args, **kwargs):
        """ 添加班级 """
        clazz_name = request.data.get("name")
        # 查询班级名是否已被添加
        clz = self.get_queryset().filter(name=clazz_name).first()

        if clz is not None:
            # 返回 失败
            return Response({"message": "班级名已存在"}, status=400)

        # 如果班级名不存在
        return super().create(request, *args, **kwargs)

    def update(self, request, pk, *args, **kwargs):
        clazz_name = request.data.get("name")
        # 查询班级名是否已被添加
        clz = self.get_queryset().filter(name=clazz_name).first()

        if clz and clz.pk != int(pk):
            return Response({"message": "班级名已存在"}, status=400)

        return super().update(request, pk=pk, *args, **kwargs)

    @action(methods=["DELETE"], url_path="batch-remove", url_name='batch-remove', detail=False)
    def batchRemove(self, request, *args, **kwargs):
        """ 批量删除 """
        # 1. 获取 传入的所有的 id
        ids = request.data

        # 2. 批量删除
        self.get_queryset().filter(id__in=ids).update(delete=True)

        return Response(status=204)

    def destroy(self, request, *args, **kwargs):
        instance = self.get_object()
        instance.delete = True
        instance.save()
        return Response(status=204)

    @action(methods=["PUT"], url_path="graduate", url_name='graduate', detail=True)
    def graduate(self, request, *args, **kwargs):
        instance = self.get_object()
        instance.status = False
        instance.save()
        serializer = self.get_serializer(instance)
        return Response(data=serializer.data, status=200)


class NoAuthView(GenericViewSet):
    queryset = User.objects.all()
    serializer_class = UserFormSerializer
    permission_classes = [AllowAny]

    @action(detail=False, methods=['GET'], url_path='clazz-list', url_name='clazz-query')
    def get_class_list(self, request, *args, **kwargs):
        """用户注册 查询班级信息"""
        # 查询所有 没有毕业的班级
        queryset = Clazz.objects.filter(status=True, delete=False).order_by('-id')
        # 序列化班级
        serializer = ClazzSerializer(queryset, many=True)

        return Response(data=serializer.data)

    @action(detail=False, methods=['POST'], url_name='register', url_path="register")
    def register(self, request, *args, **kwargs):
        """用户注册"""
        # 1. 获取界面传递的参数、
        data = request.data
        # 2. 根据用户名 查询用户表中 该用户是否 已被注册
        user = self.get_queryset().filter(username=data.get('username')).first()

        if user is not None:
            return Response(data={"status": False, "message": "用户名已被注册"})

        # 注册用户
        serializer = self.get_serializer(data=data)

        if serializer.is_valid():
            serializer.save()

            return Response(data={"status": True, "message": "注册成功"}, status=201)

        return Response(data=serializer.errors)

    @action(detail=False, methods=['POST'], url_name="login", url_path="api/token")
    def login(self, request, *args, **kwargs):

        if "username" not in request.data or "password" not in request.data:
            return Response(data={"status": False, "message": "用户名和密码均不能为空"}, status=400)

        # 获取用户名 密码
        queryset = User.objects.filter(username=request.data.get('username'))

        if not queryset.exists():
            return Response(data={"status": False, "message": "用户名或密码不正确"}, status=400)

        user = queryset.first()

        # 检验 用户是否被 禁用
        if not user.is_active:
            # 检查 redis 中是否存在 激活邮件、如果存在、直接提示 激活邮件已发送、请及时激活账号
            # 如果 不存在、 发送 激活邮件、并提示  激活邮件已发送、请及时激活账号
            return Response(data={"status": False, "message": "激活邮件已发送、请及时激活账号"}, status=400)

        # 校验密码
        if not check_password(request.data.get('password'), user.password):
            return Response(data={"status": False, "message": "用户名或密码不正确"}, status=400)
        # 使用令牌序列化器 对传入的数据进行处理
        token_serializer = MyTokenObtainPairSerializer(data=request.data)
        # 校验数据
        token_serializer.is_valid(raise_exception=True)
        # 返回序列化后的 令牌数据
        return Response(data=token_serializer.validated_data)
